Conversation
|
This was generated by AI during triage. Summary: Problems:
Solution: Checked against |
|
Thanks for catching this — you're right, the rethrow was swallowed by the unchanged Fixed in 0882362b2 (pushed to this branch): the catch now keeps the reconnect schedule (transient failures still self-heal via the existing backoff) but re-throws, so Verified: |
|
Partial overlap with #87600, now on main: the silent-misroute half is fixed (activeGateway() returns null for missing named scopes; eviction paths restore the primary explicitly). What SURVIVES here and remains wanted: the error-surfacing UX — main's ensureGatewayForProfile still does |
…y activating Rebase of NousResearch#81165 onto post-NousResearch#87600 main, slimmed to the error-surfacing UX half as requested - the silent-misroute half already landed via NousResearch#87600. - ensureGatewayForProfile: keep scheduleReconnect() on a failed secondary dial (transient failures still self-heal) but rethrow so the caller can surface the failure instead of falling through to setActive() with a closed socket (NousResearch#81094). openSecondary logs the dial target and rethrows the ORIGINAL error so reconnectSecondary's message-based fail-stop classification ("No connection with id", "no longer exists") keeps working. - profile.ensureGatewayProfile: propagate the rejection to await-callers (session actions, slash commands surface it in their own flows); the three fire-and-forget call sites (selectProfile, newSessionInProfile, voice wiring) get explicit .catch(notifyError) so the failure is always visible. - Tests: gateway.test.ts pins rethrow-without-activation plus backoff self-heal; profile-switch-failure.test.ts pins the profile-door propagation; gateway-shared-remote's pooled-reconnect test updated to the new contract (reject first, publish once the backend returns). Verified: tsc --noEmit clean; 65 tests across the gateway*/profile* suites pass; eslint and prettier clean on touched files.
db75f17 to
f748f56
Compare
|
The rebase targets the surviving UX seam cleanly, but the new rethrow skips the activation-lease cleanup immediately below this block. On current Please release the lease on both success and rejection (for example, put the dial block and lease reset under |
Clear the profile-door activation lease in a finally block whether the secondary dial succeeds or rejects. Preserve reconnect scheduling and the original error propagation. Add a regression proving a rejected activation can be pruned immediately.
|
Addressed the rejected-dial lease cleanup in the latest commit:
Validation:
|
|
Verified the lease-cleanup follow-up at
That resolves my review concern. GitHub currently reports the PR as CONFLICTING against |
…y activating Rebase of #81165 onto post-#87600 main, slimmed to the error-surfacing UX half as requested - the silent-misroute half already landed via #87600. - ensureGatewayForProfile: keep scheduleReconnect() on a failed secondary dial (transient failures still self-heal) but rethrow so the caller can surface the failure instead of falling through to setActive() with a closed socket (#81094). openSecondary logs the dial target and rethrows the ORIGINAL error so reconnectSecondary's message-based fail-stop classification ("No connection with id", "no longer exists") keeps working. - profile.ensureGatewayProfile: propagate the rejection to await-callers (session actions, slash commands surface it in their own flows); the three fire-and-forget call sites (selectProfile, newSessionInProfile, voice wiring) get explicit .catch(notifyError) so the failure is always visible. - Tests: gateway.test.ts pins rethrow-without-activation plus backoff self-heal; profile-switch-failure.test.ts pins the profile-door propagation; gateway-shared-remote's pooled-reconnect test updated to the new contract (reject first, publish once the backend returns). Verified: tsc --noEmit clean; 65 tests across the gateway*/profile* suites pass; eslint and prettier clean on touched files.
…tract) — #92265 invariant unchanged
…tract) — #92265 invariant unchanged
|
Merged via #95080 at 682a34a — your commit was cherry-picked into the consolidated salvage PR with authorship preserved, so this work carries your name in git history. Thanks for surfacing profile-switch failures instead of silently falling back to the primary socket — failing loudly here was the right call. Closing this original PR now that the consolidated branch has landed on main. Thanks for contributing to the desktop multi-gateway campaign (tracker: #94724). |
…y activating Rebase of NousResearch#81165 onto post-NousResearch#87600 main, slimmed to the error-surfacing UX half as requested - the silent-misroute half already landed via NousResearch#87600. - ensureGatewayForProfile: keep scheduleReconnect() on a failed secondary dial (transient failures still self-heal) but rethrow so the caller can surface the failure instead of falling through to setActive() with a closed socket (NousResearch#81094). openSecondary logs the dial target and rethrows the ORIGINAL error so reconnectSecondary's message-based fail-stop classification ("No connection with id", "no longer exists") keeps working. - profile.ensureGatewayProfile: propagate the rejection to await-callers (session actions, slash commands surface it in their own flows); the three fire-and-forget call sites (selectProfile, newSessionInProfile, voice wiring) get explicit .catch(notifyError) so the failure is always visible. - Tests: gateway.test.ts pins rethrow-without-activation plus backoff self-heal; profile-switch-failure.test.ts pins the profile-door propagation; gateway-shared-remote's pooled-reconnect test updated to the new contract (reject first, publish once the backend returns). Verified: tsc --noEmit clean; 65 tests across the gateway*/profile* suites pass; eslint and prettier clean on touched files.
…ch#81165 contract) — NousResearch#92265 invariant unchanged
…y activating Rebase of NousResearch#81165 onto post-NousResearch#87600 main, slimmed to the error-surfacing UX half as requested - the silent-misroute half already landed via NousResearch#87600. - ensureGatewayForProfile: keep scheduleReconnect() on a failed secondary dial (transient failures still self-heal) but rethrow so the caller can surface the failure instead of falling through to setActive() with a closed socket (NousResearch#81094). openSecondary logs the dial target and rethrows the ORIGINAL error so reconnectSecondary's message-based fail-stop classification ("No connection with id", "no longer exists") keeps working. - profile.ensureGatewayProfile: propagate the rejection to await-callers (session actions, slash commands surface it in their own flows); the three fire-and-forget call sites (selectProfile, newSessionInProfile, voice wiring) get explicit .catch(notifyError) so the failure is always visible. - Tests: gateway.test.ts pins rethrow-without-activation plus backoff self-heal; profile-switch-failure.test.ts pins the profile-door propagation; gateway-shared-remote's pooled-reconnect test updated to the new contract (reject first, publish once the backend returns). Verified: tsc --noEmit clean; 65 tests across the gateway*/profile* suites pass; eslint and prettier clean on touched files.
…ch#81165 contract) — NousResearch#92265 invariant unchanged
Fixes #81094
Problem
When switching to a secondary profile,
openSecondary/ensureGatewayForProfilecould silently fall back to the primary socket if the target backend's WebSocket failed to open (e.g. a manually started gateway process holding the profile's resources). This routed the user's messages to the wrong profile's backend and caused cross-profile session writes.Changes
apps/desktop/src/store/gateway.ts(openSecondary): rethrow connect failures with an actionable error message instead of letting the caller's catch path fall through to the primary socket.apps/desktop/src/store/profile.ts(ensureGatewayProfile): log and rethrow the switch failure instead of silently resetting the swap target.Why fail loudly instead of retrying?
A silent fallback is strictly worse than an explicit error here: the user's message would be persisted into the wrong profile's session. Failing loudly surfaces the conflict (e.g. a manually started gateway holding the profile) and the message suggests how to resolve it. Retrying against a manually held socket would loop forever.
Notes
Replaces the previous PR #81099 (same fix, rebased onto current main; the old branch was force-pushed during a botched amend and GitHub does not allow reopening it).